package cn.js.sangu.unitStore.service;

import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.js.sangu.unitStore.common.constant.SysInfo;
import cn.js.sangu.unitStore.common.exception.ServiceException;
import cn.js.sangu.unitStore.dto.FileListDTO;
import cn.js.sangu.unitStore.dto.PartAttributeDTO;
import cn.js.sangu.unitStore.entity.BomEntity;
import cn.js.sangu.unitStore.entity.ExcelData;
import cn.js.sangu.unitStore.entity.FileNas;
import cn.js.sangu.unitStore.mapper.BomMapper;
import cn.js.sangu.unitStore.service.async.BomAsyncService;
import cn.js.sangu.unitStore.service.process.ExcelProcessService;
import cn.js.sangu.unitStore.utils.LinsUtil;
import cn.js.sangu.unitStore.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * 说明：Bom服务
 * 作者：linshuo
 */
@Slf4j
@Service
@EnableAsync
public class BomService extends ServiceImpl<BomMapper, BomEntity> {

    static final String ROOT_PATH = System.getProperty("user.dir") + File.separator + "files";
    static String today = DateUtil.today();
    static String folderRootPath = ROOT_PATH + File.separator + today + File.separator;

    private final ExcelProcessService excelProcessService;
    private final BomAsyncService bomAsyncService;

    public BomService(ExcelProcessService excelProcessService, BomAsyncService bomAsyncService) {
        this.excelProcessService = excelProcessService;
        this.bomAsyncService = bomAsyncService;
    }

    /**
     * 保存Bom记录
     * 
     * @param dto
     * @return
     * @throws JsonProcessingException
     */
    public BomEntity saveInfo(BomEntity param) throws JsonProcessingException {
        param.setCreator(Objects.requireNonNull(TokenUtils.getCurrentUser()).getId());
        // 设置初始状态为正在加工
        param.setState(SysInfo.ProcessStatusProcessing); // 0: 正在加工，1: 加工成功，2: 加工失败
        // 保存清单记录
        if (!super.save(param)) {
            throw new ServiceException("Bom清单保存失败！请联系管理员");
        }
        // 在进入异步方法前获取用户 ID
        try {
            Long userId = TokenUtils.getCurrentUser() != null ? Long.valueOf(TokenUtils.getCurrentUser().getId())
                    : null;
            param.setCreator(userId != null ? userId.intValue() : null);
        } catch (Exception e) {
            log.error("获取当前用户 ID 时发生异常", e);
        }
        // 异步入口
        bomAsyncService.executiveProcess(param);
        // 返回加工结果
        return param;
    }

    private BomEntity spliceAttachInfo(BomEntity param) {
        // 临时存
        List<String> attachNameList = new LinkedList<>();
        List<Integer> ids = new LinkedList<>();
        // 工单的多个附件
        List<FileListDTO> list = param.getFileList();
        if (null != list) {
            for (FileListDTO fileList : list) {
                attachNameList.add(fileList.getName());
                // 取出原本的File对象
                FileNas fileNas = BeanUtil.toBean(fileList.getResponse().getData(), FileNas.class);
                ids.add(fileNas.getId());
            }
            param.setAttachName(list.size() > 0 ? attachNameList.toString() : "");
            param.setAttachIds(ids.toString());
            param.setAttachCount(list.size()); // 附件个数
            // dto.setFileList(dto.getFileList());
            param.setFileListJson(new ObjectMapper().valueToTree(param.getFileList()));
        }
        this.keywordReplace(param);
        return param;
    }

    public BomEntity updateInfo(BomEntity param) {
        // 设置修改人名称
        param.setModifier(Objects.requireNonNull(TokenUtils.getCurrentUser()).getId());
        if (!super.updateById(param)) {
            throw new ServiceException("更新失败！请联系管理员");
        }
        return param;
    }

    private void keywordReplace(BomEntity dto) {
        dto.setWorkName(LinsUtil.keywordReplace(dto.getWorkName(), null, null));
        dto.setWorkDescription(LinsUtil.keywordReplace(dto.getWorkDescription(), null, null));
    }

    @Async("taskExecutor") // 异步方法
    public void asyncTask() {
        long start = System.currentTimeMillis();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();
        log.info("{} ：UtilsService.asyncTask 异步方法用时{}毫秒", Thread.currentThread().getName(), end - start);
    }

    public String test() {
        return excelProcessService.test();
    }

    /**
     * 测试websocket工具
     * 
     * @param uid
     */
    public void testWs(String uid) {
        bomAsyncService.testWs(uid);
    }

}
